<template>
  <div class="puzzle-container">
    <div class="wrap" ref="wrap">
      <div class="start-page">
        <h4>
          <span @click="$router.back()">
            <svg-icon icon-class='fanhui' width="25px" height="25px" style="padding-right: 15px" class="icon"/>
          </span>
          请选择一张图片
        </h4>
        <div class="album-list">
          <div class="img-wrap" v-for="(item,index) in imgArr" :class="activeClass == index ? 'active':''" :key="index"
               @click="getItem(index)">
            <img :src="item.url" alt="">
          </div>
          <div class="img-wrap" v-if="!uploadimg">
            <div class="file-wrap" ref="filewrap">
              <input type="file" id="file" @change="onFileChange">
            </div>
          </div>

          <div class="btn" id="start" @click="startGame(activeClass)">开始游戏</div>
        </div>
      </div>

      <div class="play-page">
        <div class="deloy">倒计时：<span id="time">{{ dealtime }}</span></div>
        <div class="play-area" id="playArea">
          <div v-for="item in boxArr" :index="item" :key="item"
               :class="['piece','piece-'+(item),item===boxArractivelass?'active':'' ]"
               :style="{backgroundImage:'url('+selectedImg+')'}" @click="changePositon($event,item)"
               :ref="'piece' +item"></div>
        </div>
        <div class="btn" id="change" @click="reOrder()">重新排序</div>
        <div class="btn" id="back" @click="goBack()">返回</div>
        <van-dialog
          v-model="isDialogShow"
          title="啊呜~再来一次吧"
          @confirm="goBack"
          confirm-button-color="#ac92eb"
          className="offDialog"
        >
        </van-dialog>
        <!--闯关成功-->
        <van-dialog
          v-model="successShow"
          title="congratulate！"
          @confirm="onceAgain"
          confirm-button-color="#ac92eb"
          className="successDialog"
        >
          <div class="total-time">用时: <span id="use_time">{{ 180 - dealtime }}</span>s</div>
        </van-dialog>
      </div>
    </div>
  </div>

</template>

<script>

export default {
  name: 'PuzzleIndex',
  data () {
    return {
      startDx: 0, // 初始位移，用于返回上一页
      activeClass: -1,
      boxArractivelass: -1,
      prevIndex: null,
      curIndex: 0,
      curposArr: [],
      clickStartBtn: false,
      uploadimg: '',
      selectedImg: '',
      boxArr: new Array(9).fill(1).map((item, index) => {
        return index
      }),
      pieces: document.querySelectorAll('.piece'),
      pool: this.generateMatrix(3, 28, 20),
      matrixArr: this.upsetArr(this.generateMatrix(3, 28, 20)),
      imgArr: [
        { url: require('@/assets/images/1.jpg') },
        { url: require('@/assets/images/2.jpg') },
        { url: require('@/assets/images/3.jpg') },
        { url: require('@/assets/images/4.png') }
      ],

      wall: 0,
      prevEl: null, // 上一个元素,
      dealtime: 180,
      timer: null,
      isDialogShow: false,
      successShow: false
    }
  },
  methods: {
    getItem (index) {
      this.activeClass = index
    },
    onFileChange (e) {
      const files = e.target.files || e.dataTransfer.files
      if (!files.length) return
      this.createImage(files[0])
    },
    createImage (file) {
      //   var image = new Image();
      const reader = new FileReader()
      const vm = this

      reader.onload = e => {
        vm.uploadimg = e.target.result
        // console.log(123,e.target.result)
        this.imgArr.push({
          url: e.target.result
        })
      }
      reader.readAsDataURL(file)
    },
    startGame (picIndex) {
      if (this.activeClass === -1) {
        this.$toast.fail('请选择图片')
        return
      }
      this.timer = setInterval(this.timeStart, 1000)
      this.startDx = this.startDx - 100
      this.transformX(this.$refs.wrap, this.startDx + 'vw')
      this.selectedImg = this.imgArr[picIndex].url
      this.shuffle(document.querySelectorAll('.piece'), this.pool)
    },
    reOrder () {
      this.shuffle(document.querySelectorAll('.piece'), this.pool)
    },
    // 点击高亮并且切换对应位置 (想办法交换对应索引位置的x,y值即可)
    changePositon (e, item) {
      // 点击小图片切换位置方法
      const reg = /active/g
      // console.log(e, item);
      this.boxArractivelass = item
      const pieces = document.querySelectorAll('.piece')
      if (!this.wall) {
        this.wall = 1
        this.prevEl = e.target
        for (let i = 0, len = pieces.length; i < len; i++) {
          pieces[i].className = pieces[i].className.replace(' active', '')
        }
        !reg.test(this.className) && (this.className += ' active')
      } else {
        this.wall = 0
        const prevIndex = +this.prevEl.getAttribute('index')
        const curIndex = +e.target.getAttribute('index')

        // 置换数组
        this.swap(this.pool, prevIndex, curIndex)
        this.prevEl.style.transform =
          'translate(' +
          this.pool[prevIndex].x +
          'vw,' +
          this.pool[prevIndex].y +
          'vh' +
          ')'
        e.target.style.transform =
          'translate(' +
          this.pool[curIndex].x +
          'vw,' +
          this.pool[curIndex].y +
          'vh' +
          ')'
        // 清除样式
        this.boxArractivelass = -1
        // 校验是否成功
        if (this.isTestSuccess(this.pool)) {
          // 清除计时器
          clearInterval(this.timer)
          this.successShow = true
          console.log('111')
        }
      }
    },

    timeStart () {
      this.dealtime--
      if (this.dealtime < 1) {
        clearInterval(this.timer)
        this.isDialogShow = true
      }
    },
    // 滑动元素
    transformX (el, dx) {
      el.style.transform = 'translateX(' + dx + ')'
    },
    resetTime () {
      this.dealtime = 180
      clearInterval(this.timer)
    },
    goBack () {
      this.startDx += 100
      this.transformX(this.$refs.wrap, this.startDx + 'vw')
      this.resetTime()
    },
    onceAgain () {
      this.shuffle(document.querySelectorAll('.piece'), this.pool)
      this.startDx = -100
      this.transformX(this.$refs.wrap, this.startDx + 'vw')
      this.resetTime()
      this.dealtime = 180
      this.timer = setInterval(this.timeStart, 1000)
    },
    reStart () {
      this.startDx = this.startDx + 300
      this.transformX(this.$refs.wrap, this.startDx + 'vw')
      this.resetTime()
    },

    // 生成n维矩阵
    generateMatrix (n, dx, dy) {
      const arr = []
      let index = 0
      for (let i = 0; i < n; i++) {
        for (let j = 0; j < n; j++) {
          arr.push({ x: j * dx, y: i * dy, index: index })
          index++
        }
      }
      return arr
    },

    shuffle (els, arr) {
      this.upsetArr(arr)
      for (let i = 0, len = els.length; i < len; i++) {
        const el = els[i]
        el.setAttribute('index', i) // 将打乱后的数组索引缓存到元素中
        el.style.transform =
          'translate(' + arr[i].x + 'vw,' + arr[i].y + 'vh' + ')'
      }
    },
    upsetArr (arr) {
      // 方法1:
      return arr.sort(function () {
        return Math.random() > 0.5 ? -1 : 1
      })
    },
    // 置换数组(对应索引的x,y值进行交换)
    swap (arr, indexA, indexB) {
      [arr[indexA], arr[indexB]] = [arr[indexB], arr[indexA]]
    },

    // 校验是否成功方法
    isTestSuccess (arr) {
      return arr.every(function (item, i) {
        return item.index === i
      })
    },
    // 将canvas转化为图片
    convertCanvasToImage (canvas, quality) {
      const image = new Image()
      image.src = canvas.toDataURL('image/png', quality)
      return image
    }
  }
}
</script>

<style scoped>
.puzzle-container {
  width: 100%;
  height: 100vh;
  overflow: hidden;
  text-align: center;
}

.wrap {
  display: flex;
  width: 200vw;
  height: 100vh;
  transition: transform 1s cubic-bezier(0.52, 0.37, 0.16, 1.32);
}

div {
  box-sizing: border-box;
}

.btn {
  display: inline-block;
  padding: 10px 60px;
  width: 100vw;
  background-color: #06c;
  color: #fff;
  cursor: pointer;
  margin: 40px auto 10px;
}

#back {
  margin-top: 10px;
}

.start-page .title {
  line-height: 4em;
  font-size: 24px;
}

.start-page .album-list {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
}

.start-page .album-list .img-wrap {
  margin-bottom: 0;
  width: 33.33%;
  height: 22vh;
  overflow: hidden;
}

.start-page .album-list .img-wrap.active {
  border: 4px solid #f00;
}

.start-page .album-list .img-wrap img {
  width: 100%;
}

.start-page .album-list .img-wrap .file-wrap {
  position: relative;
  height: 100%;
  background-position: center center;
  background-size: 100%;
  background-repeat: no-repeat;
}

.start-page .album-list .img-wrap .file-wrap::before {
  content: "+";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 60px;
  color: #ccc;
  cursor: pointer;
}

.start-page .album-list .img-wrap .file-wrap input {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
}

.start-page-ft {
  position: absolute;
  width: 100%;
  bottom: 20px;
  font-size: 12px;
  text-align: center;
}

.start-page-ft a {
  color: #06c;
}

.play-page {
  background-color: #4e2503;
}

.play-page .deloy {
  padding: 10px 20px;
  color: #fff;
}

.play-page .play-area {
  position: relative;
  width: 84vw;
  height: 60vh;
  display: flex;
  flex-wrap: wrap;
  margin: 20px auto;
  outline: #ccc solid 4px;
}

.play-page .play-area.active {
  outline-color: #1f8b40;
}

.play-page .play-area .piece {
  position: absolute;
  left: 0;
  top: 0;
  width: 28vw;
  height: 20vh;
  border: 1px solid transparent;
  background-repeat: no-repeat;
  background-size: 84vw 60vh;
  transition: transform 0.6s ease-in-out;
}

.play-page .play-area .piece.active {
  border: 3px solid red;
}

.play-page .play-area .piece-0 {
  background-position: 0 0;
}

.play-page .play-area .piece-1 {
  background-position: -28vw 0;
}

.play-page .play-area .piece-2 {
  background-position: -56vw 0;
}

.play-page .play-area .piece-3 {
  background-position: 0 -20vh;
}

.play-page .play-area .piece-4 {
  background-position: -28vw -20vh;
}

.play-page .play-area .piece-5 {
  background-position: -56vw -20vh;
}

.play-page .play-area .piece-6 {
  background-position: 0 -40vh;
}

.play-page .play-area .piece-7 {
  background-position: -28vw -40vh;
}

.play-page .play-area .piece-8 {
  background-position: -56vw -40vh;
}

.result-page {
  padding-left: 20px;
  padding-right: 20px;
  background-color: #2b2929;
}

.result-page .success-text {
  padding-top: 160px;
  padding-bottom: 20px;
  font-size: 36px;
  color: #e4d721;
  font-weight: 700;
}

.result-page .total-time {
  display: block;
  margin-bottom: 30px;
  color: #fff;
  font-size: 24px;
}

.successDialog, .offDialog {
  left: 75%;
}
</style>
